package alipay.openplatform.edu.campus.jiuye.service.services.message;

import alipay.openplatform.edu.campus.jiuye.common.utils.CopyVoPo;
import alipay.openplatform.edu.campus.jiuye.common.utils.ObjectUtils;
import alipay.openplatform.edu.campus.jiuye.dao.mappers.topic.TopicInfoMapper;
import alipay.openplatform.edu.campus.jiuye.dao.mappers.user.UserTopicInfoMapper;
import alipay.openplatform.edu.campus.jiuye.model.po.TopicInfoPO;
import alipay.openplatform.edu.campus.jiuye.model.po.UserAndTopicPO;
import alipay.openplatform.edu.campus.jiuye.model.vo.TopicInfoVO;
import alipay.openplatform.edu.campus.jiuye.model.vo.UserTopicVO;
import alipay.openplatform.edu.campus.jiuye.service.iservice.message.IMessageService;
import alipay.openplatform.edu.campus.jiuye.service.iservice.message.JsonHttpClientConfig;
import com.dahantc.api.sms.json.SmsData;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created by wangdan on 16/9/24.
 */
@Service
public class MessageService implements IMessageService {

    private static final Logger LOG = LoggerFactory.getLogger(MessageService.class);

    @Autowired
    private UserTopicInfoMapper userTopicInfoMapper;
    @Autowired
    private TopicInfoMapper topicInfoMapper;
    @Autowired
    private JsonHttpClientConfig jsonHttpClientConfig;


    public void sendMessageToUser() throws Exception {
        //1 查询出所有未发短信+没有开始的活动
        List<TopicInfoVO> topicInfoVOList = querySmsTopic();
        if (topicInfoVOList != null && topicInfoVOList.size() > 0) {
            for (int i = 0; i < topicInfoVOList.size(); i++) {
                StringBuffer mobile = new StringBuffer("");
                Integer topicId = topicInfoVOList.get(i).getTopicId();
                //2 查询某个招聘会的所有报名用户并发送短信
                List<UserTopicVO> userTopicInfoVoList = querySmsUserTopicInfo(topicId);
                if (userTopicInfoVoList != null && userTopicInfoVoList.size() > 0) {
                    LOG.info("查询某个topic下所有报名的用户|MessageService|querySmsUserTopicInfo|param:topicId={},userTopicInfoVoList={}", topicId, userTopicInfoVoList);
                    String topictitle = topicInfoVOList.get(i).getTopicTitle();//主题
                    Date starttime = topicInfoVOList.get(i).getStarttime();//招聘会开始时间
//                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
//                    String strStarttime = sdf.format(starttime);
                    String strStarttime = new DateTime(starttime).toString("yyyy-MM-dd HH:mm");
//                    String place = "";
//                    if (topicInfoVOList.get(i).getTopicType() != null) {
//                        Integer topictype = topicInfoVOList.get(i).getTopicType();
//                        if (topictype == 1) {//招聘会
//                            place = userTopicInfoVoList.get(0).getSchoolName();
//                        } else {
//                            place = userTopicInfoVoList.get(0).getCityName();
//                        }
//                    }

                    StringBuffer content = new StringBuffer();
                    content.append("你已报名的")//短信内容
                            .append(topictitle)
                            .append("于")
                            .append(strStarttime)
//                            .append("在")
//                            .append(place)
                            .append("召开，请准时参加。");


                    //3 解决用户手机号大于500
                    int num = userTopicInfoVoList.size();
                    List<SmsData> smsDataList = new ArrayList<SmsData>();
                    int size = (num / 500) + 1;
                    String msgid = jsonHttpClientConfig.getMsgId();
                    String sign = jsonHttpClientConfig.getSign();
                    for (int temp = 0; temp < size; temp++) {
                        for (int mobiles = 0; mobiles < userTopicInfoVoList.size(); mobiles++) {
                            if (mobile != null) {
                                String strMobile = mobile.toString();
                                if (!strMobile.contains(userTopicInfoVoList.get(mobiles).getMobile())) {
                                    mobile.append(userTopicInfoVoList.get(mobiles).getMobile())
                                            .append(",");
                                }
                            } else {
                                LOG.info("param:userId={}", userTopicInfoVoList.get(mobiles).getUserId() + "  手机号为空");
                            }

                        }

                        smsDataList.add(new SmsData(mobile.toString(), content.toString(), msgid, sign, "14061", ""));
                        LOG.info("需要发送短信的手机号|mobile={},Now={}", mobile, new Date());
                        //发送短信
                        String falsePhones = sendSms(smsDataList);
                        LOG.info("发送短信内容|content={},Now={}", content, new Date());
                        if (falsePhones != null && falsePhones != "") {
                            //如果发送有失败手机号
                            tryFalsePhones(falsePhones, content.toString(), msgid, sign, jsonHttpClientConfig.getSubcode());
                        }
                        ((IMessageService) AopContext.currentProxy()).updateSms(topicId.toString());
                        //更新短信
//                        updateSms(topicId.toString());
                    }
                } else {
                    LOG.info("查询某个topic下所有报名的用户|MessageService|querySmsUserTopicInfo|param:topicId={},userTopicInfoVoList={}" + topicId + null);
                }
            }
        }
    }

    /**
     * 单发短信
     * 返回true代表成功,false代表失败
     *
     * @param mobile
     * @return
     */
    public boolean sendSms(String mobile, String content) {
        String account = jsonHttpClientConfig.getAccount();
        String password = jsonHttpClientConfig.getPassword();
        String sendOneRes = jsonHttpClientConfig.getJsonHttpClient().sendSms(account, password, mobile, content, jsonHttpClientConfig.getSign(), jsonHttpClientConfig.getSubcode(), jsonHttpClientConfig.getMsgId(), "");
        LOG.info("提交单条短信|响应：" + sendOneRes);

        String reportRes = jsonHttpClientConfig.getJsonHttpClient().getReport(account, password);
        LOG.info("提交单条短信|获取状态报告响应：" + reportRes);

        String smsRes = jsonHttpClientConfig.getJsonHttpClient().getSms(account, password);
        LOG.info("提交单条短信|获取上行短信响应：" + smsRes);

        //判断短信是否发送成功
        String falsePhones = strToJson(sendOneRes);
        if (StringUtils.isNotBlank(falsePhones)) {//如果短信有发送失败
            LOG.warn("提交单条短信|短信发送失败|手机号码={},短信内容={}", mobile, content);
            return false;
        }
        LOG.info("提交单条短信|短信发送成功|手机号码={},短信内容={}", mobile, content);
        return true;
    }

    /**
     * 发送短信
     *
     * @param smsDataList
     * @return
     */

    public String sendSms(List<SmsData> smsDataList) throws Exception {
        String account = jsonHttpClientConfig.getAccount();
        String password = jsonHttpClientConfig.getPassword();
        String sendBatchRes = jsonHttpClientConfig.getJsonHttpClient().sendBatchSms(account, password, smsDataList);
        LOG.info("提交批量短信响应：" + sendBatchRes);
        for (int i = 0; i < smsDataList.size(); i++) {
            LOG.info("已发送的发送短信:mobile={}", smsDataList.get(i).getPhones());
        }
        String reportRes = jsonHttpClientConfig.getJsonHttpClient().getReport(account, password);
        LOG.info("获取状态报告响应：" + reportRes);

        String smsRes = jsonHttpClientConfig.getJsonHttpClient().getSms(account, password);
        LOG.info("获取上行短信响应：" + smsRes);
        //判断短信是否发送成功
        String falsePhones = strToJson(sendBatchRes);
        if (falsePhones != null && falsePhones != "") {//如果短信有发送失败
            return falsePhones;
        }
        return null;
    }

    /**
     * 批量更新为已经发送短信
     *
     * @param topicId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSms(String topicId) {
        LOG.info("start批量更新发送短信|MessageService|updateSms|param:topicId={}" + topicId);
        int num = userTopicInfoMapper.updateSmsByPrimaryKey(Integer.parseInt(topicId));
        LOG.info("end批量更新为已经发送短信成功|MessageService|updateSms|param:topicId={}" + topicId);

    }

    /**
     * 查询出所有需要发送短信的用户信息
     *
     * @return
     */
    public List<UserTopicVO> querySmsUserTopicInfo(Integer topicId) {

        List<UserAndTopicPO> userAndTopicPOList = userTopicInfoMapper.querySmsUserTopicInfo(topicId);
        if (ObjectUtils.isNotNull(userAndTopicPOList) && userAndTopicPOList.size() > 0) {
            List<UserTopicVO> userTopicInfoVoList = CopyVoPo.copyList(userAndTopicPOList, UserTopicVO.class);
            return userTopicInfoVoList;
        } else {
            return null;
        }

    }

    /**
     * 查询出所有需要发送短信的专题
     *
     * @return
     */
    public List<TopicInfoVO> querySmsTopic() {
        List<TopicInfoPO> topicInfoPOList = topicInfoMapper.queryIfSms();
        List<TopicInfoVO> topicInfoVOList = new ArrayList<TopicInfoVO>();
        if (ObjectUtils.isNotNull(topicInfoPOList) && topicInfoPOList.size() > 0) {
            topicInfoVOList = CopyVoPo.copyList(topicInfoPOList, TopicInfoVO.class);
            return topicInfoVOList;
        } else {
            return null;
        }
    }

    /**
     * str转json
     *
     * @param strJson
     * @return
     */
    private String strToJson(String strJson) {
        JSONObject jsonObject = JSONObject.fromObject(strJson);
        String falsePhone = "";
        if (ObjectUtils.isNotNull(jsonObject.get("failPhones"))) {
            falsePhone = jsonObject.get("failPhones").toString();
        }
        return falsePhone;
    }

    /**
     * 重发失败短信重试3次
     *
     * @param falsePhone
     * @return
     */
    private Boolean tryFalsePhones(String falsePhone, String content, String msgid, String sign, String subCode) {
        List<SmsData> smsDataList = new ArrayList<SmsData>();
        smsDataList.add(new SmsData(falsePhone, content, msgid, sign, subCode, ""));
        Boolean flag = false;
        try {
            for (int time = 0; time < 3; time++) {
                String falsePhones = sendSms(smsDataList);
                if (falsePhones == null || falsePhone == "") {
                    return true;
                } else {
                    if (time == 3 && falsePhones != null) {
                        LOG.info("重发3次仍然发送失败短信:message={}", falsePhone);
                    }
                    return false;
                }
            }
        } catch (Exception e) {
            LOG.info("重发失败短信异常|MessageService|tryFalsePhones|message={}", e);
        }
        return flag;
    }

}
